package com.baiduspring.web.specialcolumn;

import com.baiduspring.config.EsIndexEnum;
import com.baiduspring.config.EsMappingFilesConfig;
import com.baiduspring.dao.entity.ResourceCollection;
import com.baiduspring.dao.entity.User;
import com.baiduspring.error.BaiduSpringException;
import com.baiduspring.function.elasticsearch.ElasticsearchHandle;
import com.baiduspring.function.elasticsearch.error.ElasticSearchException;
import com.baiduspring.function.elasticsearch.operation.Doc;
import com.baiduspring.function.elasticsearch.operation.QueryInput;
import com.baiduspring.service.resourcecollection.ResourceCollectionService;
import com.baiduspring.service.specialcolumn.SpecialColumnIndexEnum;
import com.baiduspring.service.user.UserService;
import com.baiduspring.utils.ResponseResult;
import com.baiduspring.utils.SystemCode;
import com.baiduspring.utils.bean.PageBean;
import com.baiduspring.utils.elasticsearch.ElasticSearchUtils;
import com.baiduspring.utils.elasticsearch.ScriptTextEnum;
import com.baiduspring.utils.enums.ValidStatusEnum;
import com.baiduspring.utils.servlet.WebUtils;
import com.baiduspring.utils.string.StringUtils;
import com.baiduspring.vo.ResultsVO;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;

/**
 * 专栏文章动作控制中心
 * 比如：点赞、收藏、评论等等
 *
 * @author xiongyan
 */
@RestController
@Scope("prototype")
@RequestMapping("/action")
@Slf4j
public class ActionController {
    @Resource
    private UserService userService;
    @Resource
    private ResourceCollectionService resourceCollectionService;

    /**
     * 创建评论
     *
     * @param content    平路内容
     * @param resourceId 评论资源
     * @param request    参数
     * @return 返回状态
     */
    @RequestMapping(value = "/comment", method = RequestMethod.POST)
    public ResponseResult comment(String content, String resourceId, HttpServletRequest request) {
        ResponseResult result = new ResponseResult<>();
        result.setCode(SystemCode.SUCCESS);
        result.setMessage("评论成功");

        //生成唯一的id值
        String id = StringUtils.uuid();
        long timestamp = System.currentTimeMillis();
        User user = (User) request.getSession().getAttribute("user");

        Doc<String, Object> doc = new Doc<>();
        doc.field("resourceId", resourceId);
        doc.field("content", content);
        doc.field("authorAccount", user.getAccount());
        doc.field("status", ValidStatusEnum.ENABLE.toString());
        doc.field("ip", WebUtils.getTerminalRealIP(request));
        doc.field("createDate", timestamp);
        try {
            ElasticsearchHandle.instance().indexDocs(
                    EsIndexEnum.COMMENT_INDEX.getValue(),
                    EsIndexEnum.COMMENT_TYPE.getValue(),
                    id, EsMappingFilesConfig.COMMENT, doc);
        } catch (ElasticSearchException e) {
            log.error("槽糕，发布失败！错误：{}", e);
            result.setCode(SystemCode.FAIL);
            result.setMessage("评论失败");
        }

        return result;
    }

    /**
     * 获取某资源的所有评论
     *
     * @param resourceId 资源ID
     * @return 返回评论数据列表
     */
    @GetMapping("/get_comments")
    public ResponseResult<List<ResultsVO>> getComments(String resourceId, PageBean pageBean) {
        ResponseResult<List<ResultsVO>> result = new ResponseResult<>();

        QueryBuilder queryBuilder = QueryBuilders.boolQuery()
                .must(QueryBuilders.matchPhraseQuery("resourceId", resourceId));

        String[] indies = {EsIndexEnum.COMMENT_INDEX.getValue()};
        String[] types = {EsIndexEnum.COMMENT_TYPE.getValue()};

        Map<String, Class> outputFields = Maps.newHashMap();
        outputFields.put("content", String.class);
        outputFields.put("authorAccount", Long.class);
        outputFields.put("createDate", Long.class);

        QueryInput input = new QueryInput();
        input.setIndices(indies);
        input.setTypes(types);
        input.setOutputFields(outputFields);

        input.setCurrentPage(pageBean.currentPage());
        input.setPageSize(PageBean.PAGESIZE);

        Doc<String, SortOrder> sort = new Doc<>();
        sort.put("createDate", SortOrder.DESC);
        input.setSortFields(sort);

        List<ResultsVO> list = Lists.newArrayList();
        ElasticSearchUtils.multipleFieldValueQuery(input, queryBuilder, ResultsVO.class, output -> {
            pageBean.setTotal(output.getTotal());
            pageBean.setTotalPages(output.getTotalPages());

            for (Object o : output.getResults()) {
                ResultsVO vo = (ResultsVO) o;
                userService.getByAccount(vo.getAuthorAccount()).ifPresent(user -> vo.setUser(user));
                list.add(vo);
            }
        });

        pageBean.setCurrentPage(pageBean.currentPage());
        return result.setData(list).setPageBean(pageBean);
    }

    @RequestMapping(value = "/like", method = RequestMethod.GET)
    public ResponseResult like(String resourceId) {
        ResponseResult result = new ResponseResult<>();
        result.setCode(SystemCode.SUCCESS);
        result.setMessage("点赞成功");

        String[] indies = {SpecialColumnIndexEnum.SPECIAL_COLUMN_BLOG_INDEX.getValue()};
        String[] types = {SpecialColumnIndexEnum.SPECIAL_COLUMN_BLOG_TYPE.getValue()};
        try {
            //更新点赞量
            ElasticsearchHandle.instance().scriptUpdateFieldValue(indies[0], types[0], resourceId, ScriptTextEnum.LIKES_NUM.getScript());
        } catch (Exception e) {
            result.setMessage("点赞失败");
            result.setCode(SystemCode.FAIL);
        }

        return result;
    }

    @RequestMapping(value = "/collect/{resourceId}", method = RequestMethod.GET)
    public ResponseResult collect(HttpServletRequest request, @PathVariable("resourceId") String resourceId) {
        ResponseResult result = new ResponseResult<>();
        result.setCode(SystemCode.SUCCESS);
        result.setMessage("收藏成功");
        User user = (User) request.getSession().getAttribute("user");

        ResourceCollection resourceCollection = new ResourceCollection();
        resourceCollection.setEsResourceId(resourceId);
        resourceCollection.setAccount(user.getAccount());
        resourceCollection.setEsIndexName(SpecialColumnIndexEnum.SPECIAL_COLUMN_BLOG_INDEX.getValue());
        resourceCollection.setEsIndexTypeName(SpecialColumnIndexEnum.SPECIAL_COLUMN_BLOG_TYPE.getValue());

        try {
            resourceCollectionService.add(resourceCollection, () -> {
                String[] indies = {SpecialColumnIndexEnum.SPECIAL_COLUMN_BLOG_INDEX.getValue()};
                String[] types = {SpecialColumnIndexEnum.SPECIAL_COLUMN_BLOG_TYPE.getValue()};
                try {
                    //更新点赞量
                    ElasticsearchHandle.instance().scriptUpdateFieldValue(indies[0], types[0], resourceId, ScriptTextEnum.COLLECT_NUM.getScript());
                } catch (Exception e) {
                    log.error("ES更新收藏数量错误：{}", e);
                    throw e;
                }
            });
        } catch (BaiduSpringException e) {
            result.setMessage(e.getErrorMsg());
            result.setCode(SystemCode.FAIL);
        } catch (Exception e) {
            log.error("报错啦：{}", e);
            result.setMessage("收藏失败");
            result.setCode(SystemCode.FAIL);
        }

        return result;
    }

    @RequestMapping(value = "/collect/cancel/{resourceId}", method = RequestMethod.GET)
    public ResponseResult cancelCollect(HttpServletRequest request, @PathVariable("resourceId") String resourceId) {
        ResponseResult result = new ResponseResult<>();
        result.setCode(SystemCode.SUCCESS);
        result.setMessage("取消成功");
        User user = (User) request.getSession().getAttribute("user");

        ResourceCollection resourceCollection = new ResourceCollection();
        resourceCollection.setEsResourceId(resourceId);
        resourceCollection.setAccount(user.getAccount());
        resourceCollection.setEsIndexName(SpecialColumnIndexEnum.SPECIAL_COLUMN_BLOG_INDEX.getValue());
        resourceCollection.setEsIndexTypeName(SpecialColumnIndexEnum.SPECIAL_COLUMN_BLOG_TYPE.getValue());

        try {
            resourceCollectionService.cancel(resourceCollection, () -> {
                String[] indies = {SpecialColumnIndexEnum.SPECIAL_COLUMN_BLOG_INDEX.getValue()};
                String[] types = {SpecialColumnIndexEnum.SPECIAL_COLUMN_BLOG_TYPE.getValue()};
                try {
                    //更新点赞量
                    ElasticsearchHandle.instance().scriptUpdateFieldValue(indies[0], types[0], resourceId, ScriptTextEnum.SUB_COLLECT_NUM.getScript());
                } catch (Exception e) {
                    log.error("ES更新收藏数量错误：{}", e);
                    throw e;
                }
            });
        } catch (BaiduSpringException e) {
            result.setMessage("取消失败");
            result.setCode(SystemCode.FAIL);
        } catch (Exception e) {
            result.setMessage("取消失败");
            result.setCode(SystemCode.FAIL);
        }

        return result;
    }


}
